/*********************************************************************
*
* Software License Agreement (BSD License)
*
*  Copyright (c) 2009, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of Willow Garage, Inc. nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*
* Author: Eitan Marder-Eppstein
*********************************************************************/
#ifndef BASE_LOCAL_PLANNER_GOAL_FUNCTIONS_H_
#define BASE_LOCAL_PLANNER_GOAL_FUNCTIONS_H_

#include <ros/ros.h>
#include <nav_msgs/Odometry.h>
#include <nav_msgs/Path.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Point.h>
#include <tf2_ros/buffer.h>
#include <string>
#include <cmath>
#include <angles/angles.h>
#include <costmap_2d/costmap_2d.h>

namespace base_local_planner
{

/** 返回距离的平方来检测是否到达目标点
 * @brief  return squared distance to check if the goal position has been achieved
 * @param  global_pose The pose of the robot in the global frame 全局位姿
 * @param  goal_x The desired x value for the goal 目标点x坐标
 * @param  goal_y The desired y value for the goal 目标点y坐标
 * @return distance to goal 到目标点距离
 */
double getGoalPositionDistance(const geometry_msgs::PoseStamped &global_pose, double goal_x, double goal_y);

/** 返回到目标的角度差来检查目标方向是否已经实现
 * @brief  return angle difference to goal to check if the goal orientation has been achieved
 * @param  global_pose The pose of the robot in the global frame
 * @param  goal_x The desired x value for the goal
 * @param  goal_y The desired y value for the goal
 * @return angular difference
 */
double getGoalOrientationAngleDifference(const geometry_msgs::PoseStamped &global_pose, double goal_th);

/** 发布一个可视化的计划
 * @brief  Publish a plan for visualization purposes
 * @param  path The plan to publish
 * @param  pub The published to use
 * @param  r,g,b,a The color and alpha value to use when publishing
 */
void publishPlan(const std::vector<geometry_msgs::PoseStamped> &path, const ros::Publisher &pub);

/** 删减全局规划路径中远远落后于机器人的部分
 * @brief  Trim off parts of the global plan that are far enough behind the robot
 * @param global_pose The pose of the robot in the global frame
 * @param plan The plan to be pruned
 * @param global_plan The plan to be pruned in the frame of the planner
 */
void prunePlan(const geometry_msgs::PoseStamped &global_pose, std::vector<geometry_msgs::PoseStamped> &plan,
               std::vector<geometry_msgs::PoseStamped> &global_plan);

/** 将机器人的全局规划从规划框架转换为代价地图框架; 只选择代价地图区域内计划的(第一部分)部分。
 * @brief  Transforms the global plan of the robot from the planner frame to the frame of the costmap,
 * selects only the (first) part of the plan that is within the costmap area.
 * @param tf A reference to a transform listener
 * @param global_plan The plan to be transformed
 * @param robot_pose The pose of the robot in the global frame (same as costmap)
 * @param costmap A reference to the costmap being used so the window size for transforming can be computed
 * @param global_frame The frame to transform the plan to
 * @param transformed_plan Populated with the transformed plan
 */
bool transformGlobalPlan(const tf2_ros::Buffer &tf,
                         const std::vector<geometry_msgs::PoseStamped> &global_plan,
                         const geometry_msgs::PoseStamped &global_robot_pose,
                         const costmap_2d::Costmap2D &costmap,
                         const std::string &global_frame,
                         std::vector<geometry_msgs::PoseStamped> &transformed_plan);

/** 返回规划路径中的最后一个位姿
 * @brief  Returns last pose in plan
 * @param tf A reference to a transform listener
 * @param global_plan The plan being followed
 * @param global_frame The global frame of the local planner
 * @param goal_pose the pose to copy into
 * @return True if achieved, false otherwise
 */
bool getGoalPose(const tf2_ros::Buffer &tf,
                 const std::vector<geometry_msgs::PoseStamped> &global_plan,
                 const std::string &global_frame,
                 geometry_msgs::PoseStamped &goal_pose);

/** 检查目标姿势是否已经完成
 * @brief Check if the goal pose has been achieved
 * @param tf A reference to a transform listener
 * @param global_plan The plan being followed
 * @param costmap_ros A reference to the costmap object being used by the planner
 * @param global_frame The global frame of the local planner
 * @param base_odom The current odometry information for the robot
 * @param rot_stopped_vel The rotational velocity below which the robot is considered stopped
 * @param trans_stopped_vel The translational velocity below which the robot is considered stopped
 * @param xy_goal_tolerance The translational tolerance on reaching the goal
 * @param yaw_goal_tolerance The rotational tolerance on reaching the goal
 * @return True if achieved, false otherwise
 */
bool isGoalReached(const tf2_ros::Buffer &tf,
                   const std::vector<geometry_msgs::PoseStamped> &global_plan,
                   const costmap_2d::Costmap2D &costmap,
                   const std::string &global_frame,
                   geometry_msgs::PoseStamped &global_pose,
                   const nav_msgs::Odometry &base_odom,
                   double rot_stopped_vel, double trans_stopped_vel,
                   double xy_goal_tolerance, double yaw_goal_tolerance);

/** 检查机器人是否停止
 * @brief  Check whether the robot is stopped or not
 * @param base_odom The current odometry information for the robot
 * @param rot_stopped_velocity The rotational velocity below which the robot is considered stopped
 * @param trans_stopped_velocity The translational velocity below which the robot is considered stopped
 * @return True if the robot is stopped, false otherwise
 */
bool stopped(const nav_msgs::Odometry &base_odom, const double &rot_stopped_velocity, const double &trans_stopped_velocity);

};
#endif
